#include "junix.h"
using namespace std;

struct gen {
	uint64_t n;
	gen(uint64_t i=0):n(i){ }
	uint64_t operator()() {
		return n++;
	}
};

uint64_t prime_less_100[] = {
	2, 3, 5, 7, 11, 13, 17, 
	19, 23, 29, 31, 37, 41, 
	43, 47, 53, 59, 61, 67, 
	71, 73, 79, 83, 89, 97
};

struct divided: public unary_function<uint64_t,bool> {
	bool operator()(uint64_t v) const {
		int sz = sizeof(prime_less_100)/sizeof(uint64_t);
		for (int i=0;i<sz;i++) {
			if (v%prime_less_100[i]==0)
				return true;
		}
		return false;
	}
};

struct is_prime: public unary_function<uint64_t,bool>  {
	bool operator()(uint64_t v) const {
		uint64_t sqrt = static_cast<uint64_t>(sqrtl(v));
		for (uint64_t i=2;i<= sqrt;i++) {
			if (v%i==0)
				return false;
		}
		return true;
	}
};

void next_prime(uint64_t  beg) {
	std::vector<uint64_t> v(1000);
	std::generate(v.begin(),v.end(),gen(beg));

	if (beg>100)
		v.erase(remove_if(v.begin(),v.end(),divided()), v.end());

	v.erase(remove_if(v.begin(),v.end(),is_prime()),v.end());
	copy(v.begin(),v.end(),std::ostream_iterator<uint64_t>(std::cout," "));
	std::cout<<std::endl;
}

int main(int argc, char **argv)
{
	uint64_t v = 0xFF0FFF;
	next_prime(v);
	return 0;
}
